<template>
  <div class="smart-input-wrapper">
    <el-input
      ref="inputRef"
      v-model="inputValue"
      v-bind="$attrs"
      @input="handleTextInput"
      @keydown="handleKeydown"
      @focus="handleFocus"
      @blur="handleBlur" />

    <!-- 智能匹配建议 -->
    <div v-if="showSuggestions && bestMatch" class="suggestions-panel">
      <div class="suggestions-header">最佳匹配建议 (按Tab键补全)</div>
      <div
        v-for="item in bestMatch"
        :key="item.id"
        :class="['suggestion-item', 'active']"
        @click="applySuggestion(item)">
        <div class="suggestion-content" v-html="item.highlightedContent"></div>
        <div class="suggestion-similarity">匹配度: {{ Math.round(item.similarity * 100) }}%</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, nextTick } from 'vue'
import { commontermsGet } from '@/api/filingReview/register.js'

interface Article {
  content: string
  similarity?: number
  highlightedContent?: string
}

interface Props {
  modelValue?: string
  articleDatabase?: Article[]
  minLength?: number
  maxSuggestions?: number
  contentType?: string
  preId?: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  articleDatabase: () => [],
  minLength: 2,
  maxSuggestions: 5,
  contentType: '1',
  preId: '', // 案由选中的id
})

const emit = defineEmits<{
  'update:modelValue': [value: string]
  select: [item: Article]
}>()

const inputRef = ref()
const showSuggestions = ref(false)
const suggestions = ref<Article[]>([])
const selectedIndex = ref(0)
const isFocused = ref(false)
const currentKeyword = ref('')

// 双向绑定
const inputValue = computed({
  get: () => props.modelValue,
  set: value => {
    emit('update:modelValue', value)
  },
})

// 最佳匹配项（只显示一个）
const bestMatch = computed(() => {
  if (suggestions.value.length === 0) return null
  return suggestions.value.slice(0, props.maxSuggestions)
})

// 默认文章库
const defaultArticles: Article[] = []

// 获取文章库
const getArticleDatabase = (content: string) => {
  return new Promise(async resolve => {
    const res = await commontermsGet({
      termType: props.contentType || '1',
      pageSize: 9999,
      pageNum: 1,
      status: 0,
      parentId: props.contentType === '3' ? props.preId : '',
      content: content,
    })
    if (res.data.length) {
      resolve(res.data)
    } else {
      resolve(props.articleDatabase.length > 0 ? props.articleDatabase : defaultArticles)
    }
  })
}

// 计算文本相似度（简化版）
const calculateSimilarity = (str1: string, str2: string): number => {
  if (!str1 || !str2) return 0

  const text1 = str1.toLowerCase()
  const text2 = str2.toLowerCase()

  // 完全包含匹配
  if (text2.includes(text1)) return 0.9
  if (text1.includes(text2)) return 0.8

  // 关键词匹配
  const keywords1 = text1.split(/[\s，。！？；：、]+/).filter(k => k.length > 0)
  const keywords2 = text2.split(/[\s，。！？；：、]+/).filter(k => k.length > 0)

  let matches = 0
  for (const keyword of keywords1) {
    if (keyword.length < 2) continue
    if (keywords2.some(k => k.includes(keyword) || keyword.includes(k))) {
      matches++
    }
  }

  return matches / Math.max(keywords1.length, keywords2.length)
}

// 高亮匹配的关键词
const highlightKeywords = (text: string, keywords: string[]): string => {
  if (!keywords.length) return text

  let result = text
  keywords.forEach(keyword => {
    if (keyword.length >= 2) {
      const regex = new RegExp(`(${keyword})`, 'gi')
      result = result.replace(regex, '<mark class="highlight">$1</mark>')
    }
  })

  return result
}

// 文本输入处理
const handleTextInput = async (value: string) => {
  if (!value || value.length < props.minLength) {
    showSuggestions.value = false
    return
  }

  // 获取最后输入的关键词
  const words = value
    .trim()
    .split(/[\s，。！？；：、]+/)
    .filter(w => w.length > 0)
  const lastWord = words[words.length - 1]

  if (lastWord.length < props.minLength) {
    showSuggestions.value = false
    return
  }

  // 保存当前关键词
  currentKeyword.value = lastWord
  // 搜索匹配的文章
  const database = await getArticleDatabase(currentKeyword.value)
  const matches = database
    .map(article => ({
      ...article,
      similarity: calculateSimilarity(lastWord, article.content), // 只匹配内容
      highlightedContent: highlightKeywords(article.content, [lastWord]),
    }))
    .filter(item => item.similarity > 0.1)
    .sort((a, b) => b.similarity - a.similarity)
  // .slice(0, 1) // 只取最佳匹配的一项
  suggestions.value = matches
  showSuggestions.value = matches.length > 0 && isFocused.value
  selectedIndex.value = 0
}

// 键盘事件处理
const handleKeydown = (event: KeyboardEvent) => {
  if (!showSuggestions.value || bestMatch.value === null) return

  switch (event.key) {
    case 'Tab':
    case 'Enter':
      if (showSuggestions.value && bestMatch.value.length) {
        event.preventDefault()
        applySuggestion(bestMatch.value[0])
      }
      break
    case 'Escape':
      showSuggestions.value = false
      break
  }
}

// 应用建议
const applySuggestion = (item: Article) => {
  // 直接用匹配的内容覆盖输入框
  emit('update:modelValue', item.content)
  emit('select', item)
  showSuggestions.value = false

  // 聚焦输入框
  nextTick(() => {
    inputRef.value?.focus()
  })
}

// 焦点事件
const handleFocus = () => {
  isFocused.value = true
  // 如果有内容，重新触发搜索
  if (inputValue.value && inputValue.value.length >= props.minLength) {
    handleTextInput(inputValue.value)
  }
}

const handleBlur = () => {
  isFocused.value = false
  // 延迟隐藏，以便点击建议项
  setTimeout(() => {
    if (!isFocused.value) {
      showSuggestions.value = false
    }
  }, 200)
}

// 暴露方法
defineExpose({
  focus: () => inputRef.value?.focus(),
  blur: () => inputRef.value?.blur(),
})
</script>

<style scoped lang="scss">
.smart-input-wrapper {
  position: relative;
  width: 100%;
}

.suggestions-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1000;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  max-height: 300px;
  overflow-y: auto;
  margin-top: 4px;
}

.suggestions-header {
  padding: 8px 12px;
  background: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  font-size: 12px;
  color: #909399;
  font-weight: 500;
}

.suggestion-item {
  padding: 12px;
  border-bottom: 1px solid #999;
  cursor: pointer;
  transition: all 0.2s;
  margin: 5px 0;

  &:hover,
  &.active {
    background-color: #f5f7fa;
  }

  &:last-child {
    border-bottom: none;
  }
}

.suggestion-content {
  color: #606266;
  font-size: 12px;
  line-height: 1.4;
  margin-bottom: 6px;
}

.suggestion-similarity {
  font-size: 11px;
  color: #909399;
  text-align: right;
}

/* 高亮样式 */
:deep(.highlight) {
  background-color: #fff3cd;
  color: #856404;
  padding: 1px 2px;
  border-radius: 2px;
  font-weight: 500;
}

/* 响应式适配 */
@media (max-width: 768px) {
  .suggestions-panel {
    max-height: 200px;
  }

  .suggestion-item {
    padding: 8px;
  }

  .suggestion-content {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    overflow: hidden;
  }
}
</style>
